#include "PreCompile.hpp"
#include "GeneratedFiles.hpp"
#include "Task.hpp"
#include "Project.hpp"

namespace BuildNG
{
  ////////////
  // GeneratedFiles
  void GeneratedFiles::init()
  {
    Glib::RefPtr<InputFilesTypeInfo> type_info(new InputFilesTypeInfo);
    type_info->set_create_func_from_ctor<GeneratedFiles>();
    type_info->set_xml_tag_name("generated");
    input_files_types_registry.register_type(type_info);
  }

  void GeneratedFiles::shutdown()
  {
  }

  typedef std::string ParseFileListException;

  std::vector<Glib::ustring> parse_file_list(const Glib::ustring &file_list_str)
  {
    // will be moved to it's own class some time soon...

    std::vector<Glib::ustring> ret;
      
    const gchar *begin = file_list_str.c_str();
    const gchar *end = begin + file_list_str.bytes();
    int in_quotes = -1;
    Glib::ustring cur_file_name;
    const gchar *fragment_begin = begin;
    for(const gchar *c = begin;c != end;c++)
    {
      if(*c == ';')
      {
        if(in_quotes == -1)
        {
          cur_file_name.append(fragment_begin,c - fragment_begin);
          ret.push_back(cur_file_name);
          
          fragment_begin = c + 1;
          cur_file_name.clear();
        }
      }
      else if(*c == '\"')
      {
        cur_file_name.append(fragment_begin,c - fragment_begin);
        fragment_begin = c + 1;

        if(in_quotes == -1)
          in_quotes = (int)(c - begin);
        else
          in_quotes = -1;
      }
    }

    if(fragment_begin != end)
    {
      if(in_quotes != -1)
      {
        std::stringstream msg;
        msg << "Missing closing quotes for opening quotes at " << in_quotes;
        throw ParseFileListException(msg.str());
      }

      cur_file_name.append(fragment_begin,end - fragment_begin);
      ret.push_back(cur_file_name);
    }

    return ret;
  }
    
  void GeneratedFiles::load_from_xml(const Xml::Element &xml)
  {
    Xml::Attribute *attrib = xml.try_get_attribute("input-files");
    if(attrib)
      input_files = parse_file_list(attrib->get_value());
    else
      input_files.clear();

    attrib = xml.try_get_attribute("output-files");
    if(attrib)
    {
      output_files_specified = true;
      output_files = parse_file_list(attrib->get_value());
    }
    else
      output_files_specified = false;

    task_sequence = Glib::RefPtr<TaskSequence>(new TaskSequence);
    task_sequence->load_from_xml(xml);
  }

  std::vector<Glib::ustring> GeneratedFiles::get_files_list()
  {
    assert(!"not implemented yet");
    return std::vector<Glib::ustring>();
  }

  std::vector<Glib::ustring> GeneratedFiles::build_physical_files(BuildContext &context)
  {
    task_sequence->run(context);

    std::vector<Glib::ustring> cur_output_files;
    for(int i = 0;i < (int)output_files.size();i++)
    {
      std::vector<Glib::ustring> glob_res = super_glob(output_files[i],context.get_cur_dir());
    }

    return cur_output_files;
  }
}

